import React, {useEffect, useRef, useState} from 'react';
import {Form, Input, message} from "antd";
import './BaseView.less';
import {Editor} from "@tinymce/tinymce-react";
import {saveChapter, uploadFile} from "@/pages/book/service";
import config from "@/utils/config";

export const {prefix} = config;

const handleSave = async (fields, chapter = {pubTitle: '', pubContent: '',}) => {

  try {
    if (!fields || !Object.keys(fields).length)
      return false;
    if (chapter.pubContent === fields.pubContent && chapter.pubTitle === fields.pubTitle) {
      return false;
    }
    const res = await saveChapter({
      ...fields,
    });
    if (res?.data !== 'ok') {
      message.error(res.data.error?? '保存失败请重试');

      return false;
    }
    return true;
  } catch (error) {
    message.error('保存失败请重试！');
    return false;
  }
};

export const imgUploadHandler = async (img, success, failure, form) => {
  if (img.blob()) {
    const isGt5M = img.blob.size / 1024 / 1024 > 10;
    if (isGt5M) {
      message.warn('图片尺寸超限, 请压缩后上传');
      return;
    }
    const formData = new FormData();
    formData.append("file", img.blob(), img.filename());
    formData.append("id", form.getFieldValue("id"));
    const res = await uploadFile(formData);
    if (res?.data)
      success(res.data.url);
    else
      failure("上传失败");
  }
};

export const filePickerCallBack = async (callback, value, meta, form) => {
  // 支持的类型有：media、image、file
  if (meta.filetype === 'media') { // 媒体类型
    const input = document.createElement('input');
    input.setAttribute('type', 'file');
    input.onchange = async function() {
      const file = this.files[0];
      const formData = new FormData();
      formData.append("file", file);
      formData.append("id", form.getFieldValue("id"));
      const res = await uploadFile(formData);
      if (res?.data)
        callback(res.data.url);
    }
    input.click();
  }
};

const FormItem = Form.Item;

const BookView = ({dispatch, currentChapter={id: '', parentId: '', pubTitle: '', pubContent: ''}, isSingle=false }) => {

  const [form] = Form.useForm();
  const timerId = useRef(null);
  const editorRef = useRef(null);
  const [data, setData] = useState(currentChapter?.pubContent?? '');

  const wait3s = () => {
    if (timerId.current)
      clearTimeout(timerId.current);
    timerId.current = setTimeout(() => {
      form.submit();
    }, 500);
  };

  useEffect(() => {
    if (currentChapter && currentChapter.id) {
      form.setFieldsValue({
        id: currentChapter.id,
        parentId: currentChapter.parentId,
        pubTitle: currentChapter.pubTitle,
        pubContent: currentChapter.pubContent,
        pubStatus: currentChapter.pubStatus,
      });
      setData(currentChapter.pubContent);
    }
  }, [currentChapter]);

  useEffect(() => {
    form.setFieldsValue({pubContent: data});
    wait3s();
  }, [data]);

  const doSave = (values) => {
    handleSave(values, currentChapter).then((res) => {
      if (!res)
        return;
      !isSingle ? dispatch({ // 转发可以跳过effects，直接请求reducer
        type: 'bookSpace/updateCurChapter',
        payload: {data: values},
      }) : dispatch({
        type: 'bookSpace/updateCurBook',
        payload: {data: values},
      });
    });
  };

  const inputProp = {
    style: {
      width: '100%', padding: '0 80px 10px 40px', marginBottom: 0,
      fontSize: '30px', lineHeight: '30px', boxShadow: 'none',
      outline: 'none', overflow: 'none', whiteSpace: 'nowrap', textOverflow: 'ellipsis'
    },
  };

  const checkTitle = (_, value) => {
    const promise = Promise;

    if (!value) {
      return message.warn('请输入标题').then(() => promise.reject());
    }

    if (value.length >= 120) {
      return message.warn('标题字数不能超过120').then(() => promise.reject());
    }

    return promise.resolve();
  };

  return (
    <>
      <Form
        layout="vertical"
        style={{height: '41px'}}
        form={form}
        onFinish={doSave}
        hideRequiredMark
      >
        <FormItem name="parentId" noStyle>
          <Input type="hidden"/>
        </FormItem>
        <FormItem name="id" noStyle>
          <Input type="hidden"/>
        </FormItem>
        <FormItem name="pubStatus" noStyle>
          <Input type="hidden"/>
        </FormItem>
        <FormItem name="pubTitle"
          rules={[
            {
              required: true,
              max: 120,
            },
            {
              validator: checkTitle,
            }
          ]}
        >
          <Input
            size="large"
            {...inputProp}
            placeholder="请输入标题"
            onKeyUp={() => wait3s()}
            bordered={false}
          />
        </FormItem>
        <FormItem name="pubContent" noStyle>
          <textarea hidden
                    value={data} onChange={(e) => setData(e.target.value)}/>
        </FormItem>
      </Form>
      <Editor
        onInit={(evt, editor) => {
          editorRef.current = editor;
        }}
        init={{
          height: 'calc(100% - 47px)',
          menubar: true,
          language: 'zh_CN',
          branding: false,
          resize: false,
          object_resizing: 'img',
          images_upload_url: `${prefix}/info/upload`,
          images_upload_credentials: false,
          convert_urls: false,
          file_picker_types: 'media',
          mobile: {
            width: '100%',
            menubar: true,
            resize: false,
            object_resizing: 'img',
            toolbar: ['formatselect | fullscreen image media bold italic bullist numlist  | alignleft aligncenter alignright alignjustify link unlink undo redo | fontselect | fontsizeselect outdent indent paste | charmap emoticons pagebreak | save publish',
            ],
          },
          plugins: [
            'advlist autolink lists link image charmap print preview anchor',
            'searchreplace visualblocks code fullscreen',
            'insertdatetime media table paste wordcount help',
            'importcss save directionality visualchars template codesample hr pagebreak nonbreaking toc imagetools textpattern noneditable quickbars emoticons'
          ],
          paste_data_images: true,
          toolbar: ['formatselect | bold italic | underline strikethrough | forecolor backcolor | blockquote bullist numlist | alignleft aligncenter alignright alignjustify | link unlink | undo redo | '+
            'fontselect | fontsizeselect | outdent indent | paste removeformat | charmap emoticons | pagebreak table | image media | code preview | fullscreen publish',
          ],
          setup(ed) {
            ed.ui.registry.addButton('publish', {
              text: '发布',
              tooltip: '申请发布',
              onAction: () => {
                if ((form.getFieldValue('pubStatus') ?? '') === 'in_review') {
                  message.warn('已申请，请等待').then(() => {});
                } else if ((form.getFieldValue('pubStatus') ?? '') === 'inherit'){
                  message.info('已发布，请不要频繁修改').then();
                }
                else {
                  form.setFieldsValue({pubStatus: 'in_review'});
                  form.submit();
                  if (timerId.current)
                    clearTimeout(timerId.current);
                }
              }
            });
          },
          save_onsavecallback: () => {form.submit(); if (timerId.current) clearTimeout(timerId.current);},
          video_template_callback: (video) => `<span class="mce-preview-object mce-object-video" contenteditable="false" data-mce-object="video" data-mce-p-allowfullscreen="allowfullscreen" data-mce-p-frameborder="no" data-mce-p-scrolling="no" data-mce-p-src='${video.source}' data-mce-p-width='${video.width}' data-mce-p-height='${video.height}' data-mce-p-controls="controls" data-mce-html="%20"> <video width='${video.width}' height='${video.height}' controls="controls"> <source src='${video.source}' type='${video.sourcemime}'></source> </video> </span>`,
          images_upload_handler: (img, success, failure) => imgUploadHandler(img, success, failure, form),
          file_picker_callback: (callback, value, meta) => filePickerCallBack(callback, value, meta, form),
        }}
        onEditorChange={(e) => setData(e)}
        // onKeyUp={handleEditorChange}
        value={data}
        initialValue={currentChapter?.pubContent?? ''}
      />
    </>
  );
};

export default BookView;
